home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / indentsr / io.c < prev    next >
C/C++ Source or Header  |  1990-01-04  |  15KB  |  584 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)io.c    5.10 (Berkeley) 9/15/88";
  23. #endif /* not lint */
  24.  
  25. #include "indent_globs.h"
  26. #include <ctype.h>
  27.  
  28.  
  29. int         comment_open;
  30. static      paren_target;
  31.  
  32. dump_line()
  33. {                /* dump_line is the routine that actually
  34.                  * effects the printing of the new source. It
  35.                  * prints the label section, followed by the
  36.                  * code section with the appropriate nesting
  37.                  * level, followed by any comments */
  38.     register int cur_col,
  39.                 target_col;
  40.     static      not_first_line;
  41.  
  42.     if (ps.procname[0]) {
  43.     if (troff) {
  44.         if (comment_open) {
  45.         comment_open = 0;
  46.         fprintf(output, ".*/\n");
  47.         }
  48.         fprintf(output, ".Pr \"%s\"\n", ps.procname);
  49.     }
  50.     ps.ind_level = 0;
  51.     ps.procname[0] = 0;
  52.     }
  53.     if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
  54.     if (suppress_blanklines > 0)
  55.         suppress_blanklines--;
  56.     else {
  57.         ps.bl_line = true;
  58.         n_real_blanklines++;
  59.     }
  60.     }
  61.     else if (!inhibit_formatting) {
  62.     suppress_blanklines = 0;
  63.     ps.bl_line = false;
  64.     if (prefix_blankline_requested && not_first_line)
  65.         if (swallow_optional_blanklines) {
  66.         if (n_real_blanklines == 1)
  67.             n_real_blanklines = 0;
  68.         }
  69.         else {
  70.         if (n_real_blanklines == 0)
  71.             n_real_blanklines = 1;
  72.         }
  73.     while (--n_real_blanklines >= 0)
  74.         putc('\n', output);
  75.     n_real_blanklines = 0;
  76.     if (ps.ind_level == 0)
  77.         ps.ind_stmt = 0;    /* this is a class A kludge. dont do
  78.                  * additional statement indentation if we are
  79.                  * at bracket level 0 */
  80.  
  81.     if (e_lab != s_lab || e_code != s_code)
  82.         ++code_lines;    /* keep count of lines with code */
  83.  
  84.  
  85.     if (e_lab != s_lab) {    /* print lab, if any */
  86.         if (comment_open) {
  87.         comment_open = 0;
  88.         fprintf(output, ".*/\n");
  89.         }
  90.         while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
  91.         e_lab--;
  92.         cur_col = pad_output(1, compute_label_target());
  93.         fprintf(output, "%.*s", e_lab - s_lab, s_lab);
  94.         cur_col = count_spaces(cur_col, s_lab);
  95.     }
  96.     else
  97.         cur_col = 1;    /* there is no label section */
  98.  
  99.     ps.pcase = false;
  100.  
  101.     if (s_code != e_code) {    /* print code section, if any */
  102.         register char *p;
  103.  
  104.         if (comment_open) {
  105.         comment_open = 0;
  106.         fprintf(output, ".*/\n");
  107.         }
  108.         target_col = compute_code_target();
  109.         {
  110.         register    i;
  111.  
  112.         for (i = 0; i < ps.p_l_follow; i++)
  113.             if (ps.paren_indents[i] >= 0)
  114.             ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
  115.         }
  116.         cur_col = pad_output(cur_col, target_col);
  117.         for (p = s_code; p < e_code; p++)
  118.         if (*p == (char) 0200)
  119.             fprintf(output, "%d", target_col * 7);
  120.         else
  121.             putc(*p, output);
  122.         cur_col = count_spaces(cur_col, s_code);
  123.     }
  124.     if (s_com != e_com)
  125.         if (troff) {
  126.         int         all_here = 0;
  127.         register char *p;
  128.  
  129.         if (e_com[-1] == '/' && e_com[-2] == '*')
  130.             e_com -= 2, all_here++;
  131.         while (e_com > s_com && e_com[-1] == ' ')
  132.             e_com--;
  133.         *e_com = 0;
  134.         p = s_com;
  135.         while (*p == ' ')
  136.             p++;
  137.         if (p[0] == '/' && p[1] == '*')
  138.             p += 2, all_here++;
  139.         else if (p[0] == '*')
  140.             p += p[1] == '/' ? 2 : 1;
  141.         while (*p == ' ')
  142.             p++;
  143.         if (*p == 0)
  144.             goto inhibit_newline;
  145.         if (comment_open < 2 && ps.box_com) {
  146.             comment_open = 0;
  147.             fprintf(output, ".*/\n");
  148.         }
  149.         if (comment_open == 0) {
  150.             if ('a' <= *p && *p <= 'z')
  151.             *p = *p + 'A' - 'a';
  152.             if (e_com - p < 50 && all_here == 2) {
  153.             register char *follow = p;
  154.             fprintf(output, "\n.nr C! \\w\1");
  155.             while (follow < e_com) {
  156.                 switch (*follow) {
  157.                 case '\n':
  158.                 putc(' ', output);
  159.                 case 1:
  160.                 break;
  161.                 case '\\':
  162.                 putc('\\', output);
  163.                 default:
  164.                 putc(*follow, output);
  165.                 }
  166.                 follow++;
  167.             }
  168.             putc(1, output);
  169.             }
  170.             fprintf(output, "\n./* %dp %d %dp\n",
  171.                 ps.com_col * 7,
  172.                 (s_code != e_code || s_lab != e_lab) - ps.box_com,
  173.                 target_col * 7);
  174.         }
  175.         comment_open = 1 + ps.box_com;
  176.         while (*p) {
  177.             if (*p == BACKSLASH)
  178.             putc(BACKSLASH, output);
  179.             putc(*p++, output);
  180.         }
  181.         }
  182.         else {        /* print comment, if any */
  183.         register    target = ps.com_col;
  184.         register char *com_st = s_com;
  185.  
  186.         target += ps.comment_delta;
  187.         while (*com_st == '\t')
  188.             com_st++, target += 8;    /* ? */
  189.         while (target <= 0)
  190.             if (*com_st == ' ')
  191.             target++, com_st++;
  192.             else if (*com_st == '\t')
  193.             target = ((target - 1) & ~7) + 9, com_st++;
  194.             else
  195.             target = 1;
  196.         if (cur_col > target) {    /* if comment cant fit on this line,
  197.                      * put it on next line */
  198.             putc('\n', output);
  199.             cur_col = 1;
  200.             ++ps.out_lines;
  201.         }
  202.         while (e_com > com_st && isspace(e_com[-1]))
  203.             e_com--;
  204.         cur_col = pad_output(cur_col, target);
  205.         if (!ps.box_com) {
  206.             if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1))
  207.             if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
  208.                 com_st[1] = '*';
  209.             else
  210.                 fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
  211.         }
  212.         fwrite(com_st, e_com - com_st, 1, output);
  213.         ps.comment_delta = ps.n_comment_delta;
  214.         cur_col = count_spaces(cur_col, com_st);
  215.         ++ps.com_lines;    /* count lines with comments */
  216.         }
  217.     if (ps.use_ff)
  218.         putc('\014', output);
  219.     else
  220.         putc('\n', output);
  221. inhibit_newline:
  222.     ++ps.out_lines;
  223.     if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
  224.         prefix_blankline_requested = 1;
  225.         ps.just_saw_decl = 0;
  226.     }
  227.     else
  228.         prefix_blankline_requested = postfix_blankline_requested;
  229.     postfix_blankline_requested = 0;
  230.     }
  231.     ps.decl_on_line = ps.in_decl;    /* if we are in the middle of a
  232.                      * declaration, remember that fact for
  233.                      * proper comment indentation */
  234.     ps.ind_stmt = ps.in_stmt & ~ps.in_decl;    /* next line should be
  235.                          * indented if we have not
  236.                          * completed this stmt and if
  237.                          * we are not in the middle of
  238.                          * a declaration */
  239.     ps.use_ff = false;
  240.     ps.dumped_decl_indent = 0;
  241.     *(e_lab = s_lab) = '\0';    /* reset buffers */
  242.     *(e_code = s_code) = '\0';
  243.     *(e_com = s_com) = '\0';
  244.     ps.ind_level = ps.i_l_follow;
  245.     ps.paren_level = ps.p_l_follow;
  246.     paren_target = -ps.paren_indents[ps.paren_level - 1];
  247.     not_first_line = 1;
  248.     return;
  249. };
  250.  
  251. compute_code_target()
  252. {
  253.     register    target_col = ps.ind_size * ps.ind_level + 1;
  254.  
  255.     if (ps.paren_level)
  256.     if (!lineup_to_parens)
  257.         target_col += continuation_indent * ps.paren_level;
  258.     else {
  259.         register    w;
  260.         register    t = paren_target;
  261.  
  262.         if ((w = count_spaces(t, s_code) - max_col) > 0
  263.             && count_spaces(target_col, s_code) <= max_col) {
  264.         t -= w + 1;
  265.         if (t > target_col)
  266.             target_col = t;
  267.         }
  268.         else
  269.         target_col = t;
  270.     }
  271.     else if (ps.ind_stmt)
  272.     target_col += continuation_indent;
  273.     return target_col;
  274. }
  275.  
  276. compute_label_target()
  277. {
  278.     return
  279.     ps.pcase ? (int) (case_ind * ps.ind_size) + 1
  280.     : *s_lab == '#' ? 1
  281.     : ps.ind_size * (ps.ind_level - label_offset) + 1;
  282. }
  283.  
  284.  
  285. /*
  286.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  287.  * 
  288.  * All rights reserved
  289.  * 
  290.  * 
  291.  * NAME: fill_buffer
  292.  * 
  293.  * FUNCTION: Reads one block of input into input_buffer
  294.  * 
  295.  * HISTORY: initial coding     November 1976    D A Willcox of CAC 1/7/77 A
  296.  * Willcox of CAC    Added check for switch back to partly full input
  297.  * buffer from temporary buffer
  298.  * 
  299.  */
  300. int
  301. fill_buffer()
  302. {                /* this routine reads stuff from the input */
  303.     register char *p;
  304.     register int i;
  305.     register FILE *f = input;
  306.  
  307.     if (bp_save != 0) {        /* there is a partly filled input buffer left */
  308.     buf_ptr = bp_save;    /* dont read anything, just switch buffers */
  309.     buf_end = be_save;
  310.     bp_save = be_save = 0;
  311.     if (buf_ptr < buf_end)
  312.         return;        /* only return if there is really something in
  313.                  * this buffer */
  314.     }
  315.     for (p = buf_ptr = in_buffer;;) {
  316.     if ((i = getc(f)) == EOF) {
  317.         *p++ = ' ';
  318.         *p++ = '\n';
  319.         had_eof = true;
  320.         break;
  321.     }
  322.     *p++ = i;
  323.     if (i == '\n')
  324.         break;
  325.     }
  326.     buf_end = p;
  327.     if (p[-2] == '/' && p[-3] == '*') {
  328.     if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
  329.         fill_buffer();    /* flush indent error message */
  330.     else {
  331.         int         com = 0;
  332.  
  333.         p = in_buffer;
  334.         while (*p == ' ' || *p == '\t')
  335.         p++;
  336.         if (*p == '/' && p[1] == '*') {
  337.         p += 2;
  338.         while (*p == ' ' || *p == '\t')
  339.             p++;
  340.         if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
  341.             && p[4] == 'N' && p[5] == 'T') {
  342.             p += 6;
  343.             while (*p == ' ' || *p == '\t')
  344.             p++;
  345.             if (*p == '*')
  346.             com = 1;
  347.             else if (*p == 'O')
  348.             if (*++p == 'N')
  349.                 p++, com = 1;
  350.             else if (*p == 'F' && *++p == 'F')
  351.                 p++, com = 2;
  352.             while (*p == ' ' || *p == '\t')
  353.             p++;
  354.             if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
  355.             if (s_com != e_com || s_lab != e_lab || s_code != e_code)
  356.                 dump_line();
  357.             if (!(inhibit_formatting = com - 1)) {
  358.                 n_real_blanklines = 0;
  359.                 postfix_blankline_requested = 0;
  360.                 prefix_blankline_requested = 0;
  361.                 suppress_blanklines = 1;
  362.             }
  363.             }
  364.         }
  365.         }
  366.     }
  367.     }
  368.     if (inhibit_formatting) {
  369.     p = in_buffer;
  370.     do
  371.         putc(*p, output);
  372.     while (*p++ != '\n');
  373.     }
  374.     return;
  375. };
  376.  
  377. /*
  378.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  379.  * 
  380.  * All rights reserved
  381.  * 
  382.  * 
  383.  * NAME: pad_output
  384.  * 
  385.  * FUNCTION: Writes tabs and spaces to move the current column up to the desired
  386.  * position.
  387.  * 
  388.  * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
  389.  * 
  390.  * PARAMETERS: current        integer        The current column target
  391.  * nteger        The desired column
  392.  * 
  393.  * RETURNS: Integer value of the new column.  (If current >= target, no action is
  394.  * taken, and current is returned.
  395.  * 
  396.  * GLOBALS: None
  397.  * 
  398.  * CALLS: write (sys)
  399.  * 
  400.  * CALLED BY: dump_line
  401.  * 
  402.  * HISTORY: initial coding     November 1976    D A Willcox of CAC
  403.  * 
  404.  */
  405. pad_output(current, target)    /* writes tabs and blanks (if necessary) to
  406.                  * get the current output position up to the
  407.                  * target column */
  408.     int         current;    /* the current column value */
  409.     int         target;        /* position we want it at */
  410. {
  411.     register int curr;        /* internal column pointer */
  412.     register int tcur;
  413.  
  414.     if (troff)
  415.     fprintf(output, "\\h'|%dp'", (target - 1) * 7);
  416.     else {
  417.     if (current >= target)
  418.         return (current);    /* line is already long enough */
  419.     curr = current;
  420.     while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
  421.         putc('\t', output);
  422.         curr = tcur;
  423.     }
  424.     while (curr++ < target)
  425.         putc(' ', output);    /* pad with final blanks */
  426.     }
  427.     return (target);
  428. };
  429.  
  430. /*
  431.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  432.  * 
  433.  * All rights reserved
  434.  * 
  435.  * 
  436.  * NAME: count_spaces
  437.  * 
  438.  * FUNCTION: Find out where printing of a given string will leave the current
  439.  * character position on output.
  440.  * 
  441.  * ALGORITHM: Run thru input string and add appropriate values to current
  442.  * position.
  443.  * 
  444.  * RETURNS: Integer value of position after printing "buffer" starting in column
  445.  * "current".
  446.  * 
  447.  * HISTORY: initial coding     November 1976    D A Willcox of CAC
  448.  * 
  449.  */
  450. int
  451. count_spaces(current, buffer)
  452. /*
  453.  * this routine figures out where the character position will be after
  454.  * printing the text in buffer starting at column "current"
  455.  */
  456.     int         current;
  457.     char       *buffer;
  458. {
  459.     register char *buf;        /* used to look thru buffer */
  460.     register int cur;        /* current character counter */
  461.  
  462.     cur = current;
  463.  
  464.     for (buf = buffer; *buf != '\0'; ++buf) {
  465.     switch (*buf) {
  466.  
  467.     case '\n':
  468.     case 014:        /* form feed */
  469.         cur = 1;
  470.         break;
  471.  
  472.     case '\t':
  473.         cur = ((cur - 1) & tabmask) + tabsize + 1;
  474.         break;
  475.  
  476.     case '':        /* this is a backspace */
  477.         --cur;
  478.         break;
  479.  
  480.     default:
  481.         ++cur;
  482.         break;
  483.     }            /* end of switch */
  484.     }                /* end of for loop */
  485.     return (cur);
  486. };
  487.  
  488. int    found_err;
  489. diag(level, msg, a, b)
  490. {
  491.     if (level)
  492.     found_err = 1;
  493.     if (output == stdout) {
  494.     fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
  495.     fprintf(stdout, msg, a, b);
  496.     fprintf(stdout, " */\n");
  497.     }
  498.     else {
  499.     fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
  500.     fprintf(stderr, msg, a, b);
  501.     fprintf(stderr, "\n");
  502.     }
  503. }
  504.  
  505. writefdef(f, nm)
  506.     register struct fstate *f;
  507. {
  508.     fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
  509.         nm, f->font, nm, f->size);
  510. }
  511.  
  512. char       *
  513. chfont(of, nf, s)
  514.     register struct fstate *of,
  515.                *nf;
  516.     char       *s;
  517. {
  518.     if (of->font[0] != nf->font[0]
  519.         || of->font[1] != nf->font[1]) {
  520.     *s++ = '\\';
  521.     *s++ = 'f';
  522.     if (nf->font[1]) {
  523.         *s++ = '(';
  524.         *s++ = nf->font[0];
  525.         *s++ = nf->font[1];
  526.     }
  527.     else
  528.         *s++ = nf->font[0];
  529.     }
  530.     if (nf->size != of->size) {
  531.     *s++ = '\\';
  532.     *s++ = 's';
  533.     if (nf->size < of->size) {
  534.         *s++ = '-';
  535.         *s++ = '0' + of->size - nf->size;
  536.     }
  537.     else {
  538.         *s++ = '+';
  539.         *s++ = '0' + nf->size - of->size;
  540.     }
  541.     }
  542.     return s;
  543. }
  544.  
  545.  
  546. parsefont(f, s0)
  547.     register struct fstate *f;
  548.     char       *s0;
  549. {
  550.     register char *s = s0;
  551.     int         sizedelta = 0;
  552.     bzero(f, sizeof *f);
  553.     while (*s) {
  554.     if (isdigit(*s))
  555.         f->size = f->size * 10 + *s - '0';
  556.     else if (isupper(*s))
  557.         if (f->font[0])
  558.         f->font[1] = *s;
  559.         else
  560.         f->font[0] = *s;
  561.     else if (*s == 'c')
  562.         f->allcaps = 1;
  563.     else if (*s == '+')
  564.         sizedelta++;
  565.     else if (*s == '-')
  566.         sizedelta--;
  567.     else {
  568.         fprintf(stderr, "indent: bad font specification: %s\n", s0);
  569.         exit(1);
  570.     }
  571.     s++;
  572.     }
  573.     if (f->font[0] == 0)
  574.     f->font[0] = 'R';
  575.     if (bodyf.size == 0)
  576.     bodyf.size = 11;
  577.     if (f->size == 0)
  578.     f->size = bodyf.size + sizedelta;
  579.     else if (sizedelta > 0)
  580.     f->size += bodyf.size;
  581.     else
  582.     f->size = bodyf.size - f->size;
  583. }
  584.